package org.jin.jinaicode.service.impl;

import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryColumn;
import com.mybatisflex.core.query.QueryWrapper;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.jin.jinaicode.common.BaseResponse;
import org.jin.jinaicode.common.DeleteRequest;
import org.jin.jinaicode.common.ResultUtils;
import org.jin.jinaicode.constant.UserConstant;
import org.jin.jinaicode.exception.BusinessException;
import org.jin.jinaicode.exception.ErrorCode;
import org.jin.jinaicode.exception.ThrowUtils;
import org.jin.jinaicode.mapper.UserMapper;
import org.jin.jinaicode.model.dto.admin.UserAddDTO;
import org.jin.jinaicode.model.dto.admin.UserQueryDTO;
import org.jin.jinaicode.model.dto.admin.UserUpdateAdminDTO;
import org.jin.jinaicode.model.entity.User;
import org.jin.jinaicode.model.vo.UserAdminVO;
import org.jin.jinaicode.service.ManagerService;
import org.jin.jinaicode.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static org.jin.jinaicode.constant.UserConstant.ADMIN_ROLE;
import static org.jin.jinaicode.constant.UserConstant.USER_LOGIN_STATE;

/**
 * 管理员服务实现类
 */
@Service
public class ManagerServiceImpl implements ManagerService {

  @Resource
  private UserMapper userMapper;

  @Resource
  private UserService userService;

  // 盐值，复用UserService中的盐值
  private static final String SALT = "jinai";

  // 检查邮箱格式是否正确
  private static final String EMAIL_REGEX = "^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^-]+(\\.[a-zA-Z0-9_!#$%&'*+/=?`{|}~^-]+)*@" +
      "([a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,}$";
  private static final Pattern EMAIL_PATTERN = Pattern.compile(EMAIL_REGEX);

  /**
   * 验证邮箱格式是否正确
   */
  private boolean isValidEmail(String email) {
    if (email == null)
      return false;
    Matcher matcher = EMAIL_PATTERN.matcher(email);
    return matcher.matches();
  }

  /**
   * 生成10位随机数字分享码
   */
  private String generateShareCode() {
    Random random = new Random();
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < 10; i++) {
      sb.append(random.nextInt(10));
    }
    return sb.toString();
  }

  @Override
  public boolean isAdmin(HttpServletRequest request) {
    // 获取当前登录用户
    User user = userService.getLoginUser(request);
    return isAdmin(user);
  }

  @Override
  public boolean isAdmin(User user) {
    return user != null && ADMIN_ROLE.equals(user.getUserRole());
  }

  @Override
  public BaseResponse<Long> addUser(UserAddDTO userAddDTO, HttpServletRequest request) {
    // 1. 校验请求是否合法
    if (userAddDTO == null) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
    }

    // 2. 校验当前用户是否为管理员
    if (!isAdmin(request)) {
      throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "无管理员权限");
    }

    // 3. 校验请求参数
    String userAccount = userAddDTO.getUserAccount();
    String userPassword = userAddDTO.getUserPassword();
    String userName = userAddDTO.getUserName();
    String email = userAddDTO.getEmail();
    String userRole = userAddDTO.getUserRole();

    if (StringUtils.isAnyBlank(userAccount, userPassword)) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号或密码为空");
    }

    if (userAccount.length() < 4) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号长度过短");
    }

    if (userPassword.length() < 8) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码长度不能小于8位");
    }

    // 验证邮箱格式
    if (StringUtils.isNotBlank(email) && !isValidEmail(email)) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR, "邮箱格式不正确");
    }

    // 4. 账号不能重复
    QueryWrapper queryWrapper = QueryWrapper.create();
    queryWrapper.eq("userAccount", userAccount);
    long count = userMapper.selectCountByQuery(queryWrapper);
    if (count > 0) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号已存在");
    }

    // 5. 邮箱不能重复
    if (StringUtils.isNotBlank(email)) {
      queryWrapper = QueryWrapper.create();
      queryWrapper.eq("email", email);
      count = userMapper.selectCountByQuery(queryWrapper);
      if (count > 0) {
        throw new BusinessException(ErrorCode.PARAMS_ERROR, "邮箱已存在");
      }
    }

    // 6. 密码加密
    String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());

    // 7. 生成分享码
    String shareCode = generateShareCode();

    // 8. 创建用户
    User user = new User();
    user.setUserAccount(userAccount);
    user.setUserPassword(encryptPassword);
    user.setUserName(userName);
    user.setUserAvatar(userAddDTO.getUserAvatar());
    user.setEmail(email);
    user.setUserProfile(userAddDTO.getUserProfile());
    user.setShareCode(shareCode);

    // 设置用户角色，如果未指定则默认为普通用户
    if (StringUtils.isBlank(userRole)) {
      user.setUserRole(UserConstant.DEFAULT_ROLE);
    } else {
      // 仅允许设置为普通用户或管理员
      if (!UserConstant.DEFAULT_ROLE.equals(userRole) && !ADMIN_ROLE.equals(userRole)) {
        throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户角色不合法");
      }
      user.setUserRole(userRole);
    }

    // 保存用户
    boolean result = userService.save(user);
    if (!result) {
      throw new BusinessException(ErrorCode.OPERATION_ERROR, "添加用户失败");
    }

    return ResultUtils.success(user.getId());
  }

  @Override
  public BaseResponse<Boolean> deleteUser(DeleteRequest deleteRequest, HttpServletRequest request) {
    // 1. 校验请求是否合法
    if (deleteRequest == null || deleteRequest.getId() == null) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
    }

    // 2. 校验当前用户是否为管理员
    if (!isAdmin(request)) {
      throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "无管理员权限");
    }

    // 3. 获取要删除的用户ID
    long userId = deleteRequest.getId();

    // 4. 判断要删除的用户是否存在
    User user = userService.getById(userId);
    if (user == null) {
      throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "用户不存在");
    }

    // 5. 执行删除操作（逻辑删除）
    boolean result = userService.removeById(userId);

    return ResultUtils.success(result);
  }

  @Override
  public BaseResponse<Boolean> updateUser(UserUpdateAdminDTO userUpdateAdminDTO, HttpServletRequest request) {
    // 1. 校验请求是否合法
    if (userUpdateAdminDTO == null || userUpdateAdminDTO.getId() == null) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
    }

    // 2. 校验当前用户是否为管理员
    if (!isAdmin(request)) {
      throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "无管理员权限");
    }

    // 3. 获取要更新的用户ID
    long userId = userUpdateAdminDTO.getId();

    // 4. 判断要更新的用户是否存在
    User oldUser = userService.getById(userId);
    if (oldUser == null) {
      throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "用户不存在");
    }

    // 5. 创建更新对象
    User user = new User();
    BeanUtils.copyProperties(userUpdateAdminDTO, user);

    // 6. 如果更新了密码，需要加密
    if (StringUtils.isNotBlank(userUpdateAdminDTO.getUserPassword())) {
      String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userUpdateAdminDTO.getUserPassword()).getBytes());
      user.setUserPassword(encryptPassword);
    }

    // 7. 如果更新了邮箱，需要验证格式和唯一性
    if (StringUtils.isNotBlank(userUpdateAdminDTO.getEmail())) {
      // 验证邮箱格式
      if (!isValidEmail(userUpdateAdminDTO.getEmail())) {
        throw new BusinessException(ErrorCode.PARAMS_ERROR, "邮箱格式不正确");
      }

      // 验证邮箱是否被其他用户使用
      QueryWrapper queryWrapper = QueryWrapper.create();
      queryWrapper.eq("email", userUpdateAdminDTO.getEmail());
      queryWrapper.ne("id", userId);
      long count = userMapper.selectCountByQuery(queryWrapper);
      if (count > 0) {
        throw new BusinessException(ErrorCode.PARAMS_ERROR, "该邮箱已被使用");
      }
    }

    // 8. 如果更新了会员过期时间，需要格式转换
    if (StringUtils.isNotBlank(userUpdateAdminDTO.getVipExpireTime())) {
      try {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime vipExpireTime = LocalDateTime.parse(userUpdateAdminDTO.getVipExpireTime(), formatter);
        user.setVipExpireTime(vipExpireTime);
      } catch (Exception e) {
        throw new BusinessException(ErrorCode.PARAMS_ERROR, "会员过期时间格式不正确，应为yyyy-MM-dd HH:mm:ss");
      }
    }

    // 9. 执行更新操作
    boolean result = userService.updateById(user);

    return ResultUtils.success(result);
  }

  @Override
  public BaseResponse<UserAdminVO> getUserById(long id, HttpServletRequest request) {
    // 1. 校验当前用户是否为管理员
    if (!isAdmin(request)) {
      throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "无管理员权限");
    }

    // 2. 查询用户
    User user = userService.getById(id);
    if (user == null) {
      throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "用户不存在");
    }

    // 3. 转换为VO对象并返回
    UserAdminVO userAdminVO = getUserAdminVO(user);

    return ResultUtils.success(userAdminVO);
  }

  @Override
  public BaseResponse<Page<UserAdminVO>> listUserByPage(UserQueryDTO userQueryDTO, HttpServletRequest request) {
    // 1. 校验当前用户是否为管理员
    if (!isAdmin(request)) {
      throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "无管理员权限");
    }

    // 2. 处理查询条件
    QueryWrapper queryWrapper = QueryWrapper.create();

    // 添加查询条件
    Long id = userQueryDTO.getId();
    if (id != null) {
      queryWrapper.eq("id", id);
    }

    String userAccount = userQueryDTO.getUserAccount();
    if (StringUtils.isNotBlank(userAccount)) {
      queryWrapper.like("userAccount", userAccount);
    }

    String userName = userQueryDTO.getUserName();
    if (StringUtils.isNotBlank(userName)) {
      queryWrapper.like("userName", userName);
    }

    String email = userQueryDTO.getEmail();
    if (StringUtils.isNotBlank(email)) {
      queryWrapper.like("email", email);
    }

    String userRole = userQueryDTO.getUserRole();
    if (StringUtils.isNotBlank(userRole)) {
      queryWrapper.eq("userRole", userRole);
    }

    // 3. 处理排序
    String sortField = userQueryDTO.getSortField();
    String sortOrder = userQueryDTO.getSortOrder();

    if (StringUtils.isNotBlank(sortField)) {
      QueryColumn column = new QueryColumn(sortField);
      if ("ascend".equals(sortOrder)) {
        queryWrapper.orderBy(column, true);
      } else {
        queryWrapper.orderBy(column, false);
      }
    } else {
      // 默认按创建时间降序排列
      queryWrapper.orderBy(new QueryColumn("createTime"), false);
    }

    // 4. 分页查询
    int pageNum = userQueryDTO.getPageNum();
    int pageSize = userQueryDTO.getPageSize();

    Page<User> userPage = new Page<>(pageNum, pageSize);
    Page<User> result = userMapper.paginateWithRelations(userPage, queryWrapper);

    // 5. 转换为VO列表
    List<UserAdminVO> userAdminVOList = new ArrayList<>();
    for (User user : result.getRecords()) {
      userAdminVOList.add(getUserAdminVO(user));
    }

    // 6. 组装分页结果
    Page<UserAdminVO> voPage = new Page<>(result.getPageNumber(), result.getPageSize(), result.getTotalRow());
    voPage.setRecords(userAdminVOList);

    return ResultUtils.success(voPage);
  }

  @Override
  public UserAdminVO getUserAdminVO(User user) {
    if (user == null) {
      return null;
    }

    UserAdminVO userAdminVO = new UserAdminVO();
    BeanUtils.copyProperties(user, userAdminVO);

    return userAdminVO;
  }
}
